package com.pilipala.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pilipala.constant.LikesConstant;
import com.pilipala.constant.MessageConstant;
import com.pilipala.constant.SearchConstant;
import com.pilipala.constant.UploadConstant;
import com.pilipala.context.BaseContext;
import com.pilipala.dto.*;
import com.pilipala.entity.Blog;
import com.pilipala.entity.User;
import com.pilipala.exception.DeleteException;
import com.pilipala.exception.OrderException;
import com.pilipala.exception.UpdateException;
import com.pilipala.mapper.BlogMapper;
import com.pilipala.mapper.UserMapper;
import com.pilipala.result.PageResult;
import com.pilipala.service.BlogService;
import com.pilipala.utils.AliOssUtil;
import com.pilipala.vo.BlogVO;
import com.pilipala.vo.UserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class BlogServiceImpl implements BlogService {

    private static final Logger log = LoggerFactory.getLogger(BlogServiceImpl.class);
    @Autowired
    private AliOssUtil aliOssUtil;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private RedisTemplate<String,Long> redisTemplate;
    /**
     * 添加博客
     * @param blogDTO 博客内容
     */
    @Override
    public void create(BlogDTO blogDTO) {
        String blogContent = blogDTO.getContent();
//        根据token获取博主名称
        Long userId = BaseContext.getCurrentId();
        User user = userMapper.getUserById(BaseContext.getCurrentId());
//        设置blog相关参数
        Blog blog = new Blog();
        blog.setUserId(userId);
        blog.setUserName(user.getUserName());
        BeanUtils.copyProperties(blogDTO,blog);
        blog.setTime(new Date());
//        上传到blog
        String objectName = UploadConstant.BLOG_PRE + UUID.randomUUID() + ".html";
        String blogUrl = aliOssUtil.upload(blogContent.getBytes(), objectName);
//        设置内容路径
        blog.setContentPath(blogUrl);
        blogMapper.insert(blog);
    }

    @Override
    public PageResult listByCondition(BlogSearchDTO blogSearchDTO) {
        PageHelper.startPage(blogSearchDTO.getPage(),blogSearchDTO.getPageSize());
        Page<Blog> page = blogMapper.listByCondition(blogSearchDTO);

        List<Blog> pageResult = page.getResult();
        long total = page.getTotal();

        page.close();
        PageHelper.clearPage();

        return new PageResult(total,pageResult);
    }


    /**
     * 无条件获取所有Blog
     * @param blogSearchDTO 页码、页大小
     * @return 分页后的结果
     */
    @Override
    public PageResult list(BlogSearchDTO blogSearchDTO) {
//        分页获取数据
        PageHelper.startPage(blogSearchDTO.getPage(),blogSearchDTO.getPageSize());
        Page<Blog> page = blogMapper.list();

        long total = page.getTotal();
        List<Blog> pageResult = page.getResult();

//        关闭资源
        page.close();
        PageHelper.clearPage();
        return new PageResult(total,pageResult);
    }

    /**
     * 分页搜索
     * @param searchDTO 包括页码、页大小、搜索关键字、排序类型
     * @return 分页后的数据
     */
    @Override
    public PageResult search(SearchDTO searchDTO) {
        if (!SearchConstant.ORDERLIST.contains(searchDTO.getOrder())){
            throw new OrderException(MessageConstant.ORDER_TYPE_ERROR);
        }

        PageHelper.startPage(searchDTO.getPage(),searchDTO.getPageSize());
        Page<Blog> page = blogMapper.search(searchDTO);

        long total = page.getTotal();
        List<Blog> pageResult = page.getResult();

        page.close();
        PageHelper.clearPage();
        return new PageResult(total,pageResult);
    }


    /**
     * 根据博客Id获取博客
     * @param id 博客Id
     * @return 返沪博客数据
     */
    @Override
    public BlogVO getById(Long id) {
        BlogVO blogVO = blogMapper.getById(id);
        if (blogVO != null){
//            搜得到这个数据

//            获取到这个blog存在alioss中的objectName
            String contentPath = blogVO.getContentPath();
            String fileName = contentPath.substring(contentPath.lastIndexOf("/")+1);
            String objectName = UploadConstant.BLOG_PRE+fileName;
            String content = aliOssUtil.get(objectName);
            blogVO.setContent(content);
//            log.info(blogVO.getContent());
            Long collectionId = blogMapper.getCollectionPair(BaseContext.getCurrentId(), id);
            blogVO.setCollectionId(collectionId);

            Boolean isLike = redisTemplate.opsForSet().isMember(LikesConstant.BLOG_PRE + id, BaseContext.getCurrentId());
            blogVO.setIsLike(isLike);
        }
        return blogVO;
    }

    /**
     * 删除指定blog
     * @param id Blog的Id
     */
    @Override
    public void delete(Long id) {
        BlogVO blogVO = blogMapper.getById(id);
        Long userId = BaseContext.getCurrentId();
//        不是本人没有权限
        if (!Objects.equals(blogVO.getUserId(), userId)){
            throw new DeleteException(MessageConstant.POWER_ERROR);
        }
        blogMapper.delete(id);
    }

    /**
     * 根据blog的Id修改blog
     * @param updateBlogDTO 包括title、content、description、id--blog的
     *
     **/
    @Override
    public void update(UpdateBlogDTO updateBlogDTO) {
        String blogContent = updateBlogDTO.getContent();

        BlogVO blogVO = blogMapper.getById(updateBlogDTO.getId());

        if (!blogVO.getUserId().equals(BaseContext.getCurrentId())){
            throw new UpdateException(MessageConstant.POWER_ERROR);
        }

        //        设置blog相关参数
        Blog blog = new Blog();
        BeanUtils.copyProperties(updateBlogDTO,blog);
        blog.setTime(new Date());


//        上传到blog
        String objectName = UploadConstant.BLOG_PRE + UUID.randomUUID() + ".html";
        String blogUrl = aliOssUtil.upload(blogContent.getBytes(), objectName);
//        设置内容路径
        blog.setContentPath(blogUrl);

        blogMapper.update(blog);
    }

    @Override
    public PageResult getCollection(PageinationDTO pageinationDTO) {
        PageHelper.startPage(pageinationDTO.getCurrent(),pageinationDTO.getPageSize());
        Page<Long> page = blogMapper.getCollectionByUserId(BaseContext.getCurrentId());
        List<BlogVO> blogList = new ArrayList<>();
        for (var blogId : page.getResult()){
            if (blogId == null){
                continue;
            }
            BlogVO blogVO = blogMapper.getById(blogId);
            blogList.add(blogVO);
        }
        return new PageResult(blogList.size(),blogList);
    }

    /**
     * 收藏blog
     * @param blogId 博客id
     */
    @Override
    public void collection(Long blogId) {
        Long collectionId = blogMapper.getCollectionPair(BaseContext.getCurrentId(),blogId);
        if (collectionId == null){
//            没有收藏说明是收藏操作
            blogMapper.addCollection(BaseContext.getCurrentId(),blogId);
            BlogVO blogVO = blogMapper.getById(blogId);
            blogVO.setCollectionNumber(blogVO.getCollectionNumber() + 1);

            Blog blog = new Blog();
            BeanUtils.copyProperties(blogVO,blog);
            blog.setCollectionId(null);
            blogMapper.update(blog);
        }else{
//            收藏了说明要取消收藏
            blogMapper.deleteCollection(BaseContext.getCurrentId(),blogId);
            BlogVO blogVO = blogMapper.getById(blogId);
            blogVO.setCollectionNumber(blogVO.getCollectionNumber() - 1);

            Blog blog = new Blog();
            BeanUtils.copyProperties(blogVO,blog);
            blog.setCollectionId(null);
            blogMapper.update(blog);
        }
    }

    /**
     * 点赞博客
     * @param blogId 博客Id
     */
    @Override
    public void likes(Long blogId) {
        Boolean isLikes = redisTemplate.opsForSet().isMember(LikesConstant.BLOG_PRE + blogId, BaseContext.getCurrentId());
        BlogVO blogVO = blogMapper.getById(blogId);
        Blog blog = new Blog();
        BeanUtils.copyProperties(blogVO,blog);

        if (Boolean.TRUE.equals(isLikes)){
//            如果点赞过了
            redisTemplate.opsForSet().remove(LikesConstant.BLOG_PRE+blogId,BaseContext.getCurrentId());

            blog.setLikes(blog.getLikes() - 1);
        }else{
            redisTemplate.opsForSet().add(LikesConstant.BLOG_PRE+blogId,BaseContext.getCurrentId());
            redisTemplate.expire(LikesConstant.BLOG_PRE+blogId,LikesConstant.TTL, TimeUnit.DAYS);
            blog.setLikes(blog.getLikes() + 1);
        }
        blogMapper.update(blog);
    }

}



